package com.voice.server.observer.impl;


import com.voice.server.connection.ConnectionInvoke;
import com.voice.server.entity.Device;
import com.voice.server.entity.DevicePinYinCode;
import com.voice.server.enums.DeviceStatusEnum;
import com.voice.server.enums.PushTypeEnum;
import com.voice.server.map.PinYinCodeMap;
import com.voice.server.message.MessageFactory;
import com.voice.server.message.device.PinYinCodeMessage;
import com.voice.server.observer.Observable;
import com.voice.server.observer.Observer;
import com.voice.server.repository.DeviceRepository;
import com.wangjiacai.utils.utils.PingYinUtil;
import com.wangjiacai.utils.web.service.RedisService;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;

@Component
public class CmdObservable implements Observable, InitializingBean {

    public static String hashKey="pushType";
    @Autowired
    private ConnectionInvoke connectionInvoke;
    @Autowired
    private RedisService redisService;
    @Autowired
    private Executor executor;
    @Autowired
    private List<Observer> observers;
    @Autowired
    private DeviceRepository deviceRepository;
    @Autowired
    private PinYinCodeMap pinYinCodeMap;

    @Override
    public void afterPropertiesSet(){
        List<Device> list=deviceRepository.findByStatus(DeviceStatusEnum.Online.getCode());
        list.stream().forEach(device -> redisService.hashSet(hashKey,device.getDeviceKey(),device.getPushType()));
    }

    @Override
    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void deleteObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers(String userId, String deviceKey,Object param) {
        Integer pushType=redisService.hashGet(hashKey,deviceKey,Integer.class);
        if(pushType==null) return;
        if(param instanceof String){
            if(pushType== PushTypeEnum.Text.getCode()||pushType==PushTypeEnum.TextMatch.getCode()){
                observers.forEach(observer -> CompletableFuture.runAsync(
                        () -> observer.update(this,userId,deviceKey,MessageFactory.getSdkMessage(userId,deviceKey, (String) param),pushType)
                        , executor)
                );
            }else {
                String pinyin= PingYinUtil.getPingYinWithOutTone((String) param);
                List<DevicePinYinCode> list=pinYinCodeMap.get(deviceKey);
                for(DevicePinYinCode devicePinYinCode:list){
                    if(pinyin.indexOf(devicePinYinCode.getPinyin())!=-1){
                        PinYinCodeMessage pinYinCodeMessage=new PinYinCodeMessage(devicePinYinCode.getCode());
                        connectionInvoke.sendDeviceMessage(deviceKey,pinYinCodeMessage.getTopic(),pinYinCodeMessage);
                        return;
                    }
                }
                return;
            }
        }
        observers.forEach(observer -> CompletableFuture.runAsync(() -> observer.update(this,userId,deviceKey,param,pushType), executor));
    }

}
